package edu.fiu.cis.personalize.server.graph.update;

import java.util.HashMap;

import edu.fiu.cis.personalize.server.graph.Node;
import edu.fiu.cis.personalize.server.graph.NodeType;
import edu.fiu.cis.personalize.server.graph.store.NullHashMap;

public class GraphUpdateFactory {

	@SuppressWarnings("serial")
	private static HashMap<NodeType, HashMap<NodeType, GraphUpdate<? extends Node, ? extends Node>>> map = new NullHashMap<NodeType, HashMap<NodeType, GraphUpdate<? extends Node, ? extends Node>>>() {

		@Override
		protected HashMap<NodeType, GraphUpdate<? extends Node, ? extends Node>> createEmptyValue(
				NodeType key) {
			return new HashMap<NodeType, GraphUpdate<? extends Node, ? extends Node>>();
		}
	};

	static {
		_add_(new DocumentQueryUpdate());
		_add_(new DocumentUserUpdate());
		_add_(new GroupGroupUpdate());
		_add_(new GroupQueryUpdate());
		_add_(new GroupUserUpdate());
		_add_(new QueryDocumentUpdate());
		_add_(new QueryQueryUpdate());
		_add_(new QueryUserUpdate());
		_add_(new UserDocumentUpdate());
		_add_(new UserGroupUpdate());
		_add_(new UserQueryUpdate());
		_add_(new QueryGroupUpdate());
	}

	private static <N extends Node, M extends Node> void _add_(
			GraphUpdate<N, M> e) {
		map.get(e.type1()).put(e.type2(), e);
	}

	@SuppressWarnings("unchecked")
	public static final <N extends Node, M extends Node> void update(N n1, M n2) {
		GraphUpdate<N, M> updater = (GraphUpdate<N, M>) map.get(n1.getType())
				.get(n2.getType());
		updater.update(n1, n2);
	}

	@SuppressWarnings("unchecked")
	public static final <N extends Node, M extends Node> double getAuthorityTransferRate(
			N n1, M n2) {
		return ((GraphUpdate<N, M>) map.get(n1.getType()).get(n2.getType()))
				.getAuthorityTransferRate(n1, n2);
	}

}
